package com.lfs.admin.manager;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.sql.*;
import java.sql.Date;
import java.time.LocalDate;
import java.util.*;
import javax.sql.DataSource;

@Component
public class WalletDailySummaryTask {

    private final DataSource dataSource;

    public WalletDailySummaryTask(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    // 每天凌晨1点执行
    @Scheduled(cron = "0 0 1 * * ?")
    @Transactional
    public void generateDailySummary() {
        LocalDate yesterday = LocalDate.now().minusDays(1);
        generateDailySummaryForDate(yesterday);
    }

    public void generateDailySummaryForDate(LocalDate date) {
        // 1. 查询所有有交易记录的代理商
        Set<String> agentPhones = getAgentsWithTransactions(date);

        // 2. 为每个代理商生成日汇总
        for (String agtPhone : agentPhones) {
            generateAgentDailySummary(agtPhone, date);
        }
    }

    private Set<String> getAgentsWithTransactions(LocalDate date) {
        Set<String> phones = new HashSet<>();
        String sql = "SELECT DISTINCT agt_phone FROM lfs_agt_wallet_detail " +
                "WHERE DATE(create_time) = ?";

        try (Connection conn = dataSource.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            pstmt.setDate(1, Date.valueOf(date));
            ResultSet rs = pstmt.executeQuery();

            while (rs.next()) {
                phones.add(rs.getString("agt_phone"));
            }
        } catch (SQLException e) {
            throw new RuntimeException("获取有交易的代理商列表失败", e);
        }
        return phones;
    }

    private void generateAgentDailySummary(String phone, LocalDate date) {
        // 查询当日的交易汇总
        DailySummary summary = calculateDailySummary(phone, date);

        // 插入或更新日汇总记录
        String upsertSql = "INSERT INTO lfs_agt_wallet_daily " +
                "(agt_phone, record_date, recharge_amount, consume_amount, refund_amount, create_time, update_time) " +
                "VALUES (?, ?, ?, ?, ?, NOW(), NOW()) " +
                "ON DUPLICATE KEY UPDATE " +
                "recharge_amount = VALUES(recharge_amount), " +
                "consume_amount = VALUES(consume_amount), " +
                "refund_amount = VALUES(refund_amount), " +
                "update_time = NOW()";

        try (Connection conn = dataSource.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(upsertSql)) {

            pstmt.setString(1, phone);
            pstmt.setDate(2, Date.valueOf(date));
            pstmt.setBigDecimal(3, summary.rechargeAmount);
            pstmt.setBigDecimal(4, summary.consumeAmount);
            pstmt.setBigDecimal(5, summary.refundAmount);

            pstmt.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException("生成代理商日汇总失败: " + phone, e);
        }
    }

    private DailySummary calculateDailySummary(String phone, LocalDate date) {
        DailySummary summary = new DailySummary();
        String sql = "SELECT transaction_type, SUM(amount) as total_amount " +
                "FROM lfs_agt_wallet_detail " +
                "WHERE agt_phone = ? AND DATE(create_time) = ? " +
                "GROUP BY transaction_type";

        try (Connection conn = dataSource.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            pstmt.setString(1, phone);
            pstmt.setDate(2, Date.valueOf(date));
            ResultSet rs = pstmt.executeQuery();

            while (rs.next()) {
                int type = rs.getInt("transaction_type");
                BigDecimal amount = rs.getBigDecimal("total_amount");

                switch (type) {
                    case 1: // 充值
                        summary.rechargeAmount = amount.abs();
                        break;
                    case 2: // 上架
                        summary.consumeAmount = amount.abs();
                        break;
                    case 3: // 退款
                        summary.refundAmount = amount.abs();
                        break;
                }
            }
        } catch (SQLException e) {
            throw new RuntimeException("计算日汇总数据失败: " + phone, e);
        }
        return summary;
    }

    private static class DailySummary {
        BigDecimal rechargeAmount = BigDecimal.ZERO;
        BigDecimal consumeAmount = BigDecimal.ZERO;
        BigDecimal refundAmount = BigDecimal.ZERO;
    }
}
